home *** CD-ROM | disk | FTP | other *** search
/ 8bitfiles.net/archives / archives.tar / archives / compuserve-file-archive / 07 CP_M / HIST.ARK / HISTRSX.MAC < prev   
Encoding:
Text File  |  1991-04-26  |  12.3 KB  |  601 lines

  1. ;HISTRSX.MAC 07/25/86  Jim Lopushinsky  Meadowlark 403-435-6579
  2. ;
  3. ; Copyright (c) 1986 Jim Lopushinsky
  4. ;
  5. ; Requires Z80 processor and CP/M Plus
  6. ;
  7. ; A History command for CP/M+ similiar to Andrew McLean's BUFFER+,
  8. ; but much smaller and simpler.  This RSX has the same features as
  9. ; BUFFER+, with the added feature of seperation of CCP and user history
  10. ; lines.  The decrease in size is acheived by using CP/M 3's built in
  11. ; console input I/O redirection features that the CCP, SUBMIT, and GET
  12. ; uses to redirect console input to a text string in RAM.  Thus, all the
  13. ; editting code that is in the BDOS is not duplicated here.  The only
  14. ; intercept code is for ^W (scroll back), ^V (scroll ahead),
  15. ; ^L (list history lines).  This RSX is safe to remove at any time
  16. ; by simply setting the remove flag.  Although some ideas were lifted
  17. ; from BUFFER+, the code is all original.  This RSX is quite safe to
  18. ; use beneath or on top of BYE or within Submit files (even nested).
  19. ;
  20.     .z80
  21.  
  22. buff_len    equ    300        ; Length of buffer
  23. page_size    equ    23        ; Lines to display before pause
  24.  
  25. ctrlw        equ    'W'-40h
  26. ctrlv        equ    'V'-40h
  27. ctrll        equ    'L'-40h
  28. ctrlx        equ    'X'-40h
  29. ctrlk        equ    'K'-40h
  30.  
  31. ;..........
  32. ;
  33. ; RSX header
  34. ;
  35.     dw    0,0,0
  36.     jp    ftest
  37. next:    jp    0
  38. prev:    dw    0
  39. remove:    db    0ffh
  40.     db    0
  41.     db    'HIST    '
  42.     db    0,0,0
  43.  
  44. ftest:
  45.     ld    a,c            ; Get the function
  46.     cp    60            ; RSX function?
  47.     jr    z,rsxtest        ; Jump if could be for us
  48.     ld    a,(initf)
  49.     or    a            ; Initialized?
  50.     jr    z,next            ; Ignore if not
  51.     ld    a,c            ; Get BDOS function
  52.     cp    10            ; Get Line?
  53.     jr    nz,next            ; Ignore if not
  54.     ld    a,e
  55.     or    d            ; Using initialized DMA?
  56.     jr    z,next            ; Ignore if using DMA
  57.     ld    hl,(scbbase)
  58.     ld    l,0bah            ; Point to console redirected addr
  59.     ld    a,(hl)
  60.     inc    l
  61.     or    (hl)            ; CONIN redirection?
  62.     jr    nz,next            ; Ignore if redirection
  63.     ld    l,0b4h            ; Point to CCP flags
  64.     ld    a,(hl)
  65.     and    80h            ; Isolate CCP active bit
  66.     ld    (ccpflag),a        ; Save for redirection routines
  67.     push    de            ; Save buffer address
  68.     xor    a
  69.     ld    (conchar),a        ; Init for BIOS routines
  70.     ld    hl,0ffffh
  71.     ld    (cur_line),hl        ; Init current line address
  72.     call    patch            ; Patch BIOS
  73.     call    next            ; Fill the buffer
  74.     call    unpatch            ; Restore original BIOS vectors
  75.     pop    de            ; Restore buffer address
  76.     inc    de            ; Point to length
  77.     ld    a,(de)
  78.     or    a            ; Anything there?
  79.     ret    z            ; Ignore if empty
  80.     ld    c,a
  81.     ld    b,0            ; Set up BC = length
  82.     inc    de            ; Point to start of text
  83.     call    add_line        ; Add current line to storage
  84.     ret
  85.  
  86. ;......
  87. ;
  88. ; Here to initialize or unload previous HISTORY RSX
  89. ;
  90. ;
  91. rsxtest:
  92.     ld    a,(de)            ; Get RSX function
  93.     cp    56            ; Clear buffer function?
  94.     jr    z,is56
  95.     cp    55            ; Our init function?
  96.     jr    nz,next            ; Ignore if not
  97. is55:
  98.     ld    a,(initf)
  99.     or    a            ; Already initilized?
  100.     jr    z,notinit        ; Jump if not init.
  101.     ld    a,0ffh
  102.     ld    (remove),a        ; Set remove flag
  103.     inc    a
  104.     ld    (initf),a        ; Reset init flag
  105.     ld    de,delmsg
  106.     ld    c,9
  107.     call    next            ; Say that we will die.
  108.     xor    a
  109.     ret
  110.  
  111. notinit:
  112.     call    next            ; See if we are cloned
  113.     or    a
  114.     ret    z            ; If cloned, just return
  115.     ld    (initf),a        ; Set init flag
  116.     xor    a
  117.     ld    (remove),a        ; Reset remove flag
  118.     ld    de,scbpb
  119.     ld    c,49
  120.     call    next            ; Get SCB address
  121.     ld    (scbbase),hl
  122.     ld    l,68h            ; Point to SCB wboot jump
  123.     ld    de,6            ; Vectors are 6 apart
  124.     ld    b,4            ; 4 vectors to mod
  125.     ld    a,21h            ; LD H,nnnn op code
  126. modloop:
  127.     ld    (hl),a            ; Change JP nnn to LD H,nnn
  128.     add    hl,de            ; Bump offset
  129.     djnz    modloop
  130.     ld    hl,(1)            ; Get BIOS wboot addr
  131.     ld    a,9
  132.     call    addhla            ; Offset to CONOUT
  133.     ld    (xconout),hl        ; Save for CONOUT calls
  134.     ld    de,histmsg
  135.     ld    c,9
  136.     call    next            ; Say that we are active
  137.  
  138. is56:
  139.     ld    hl,buff_start
  140.     ld    (next_free),hl        ; Init next free addr
  141.     ld    hl,0
  142.     ld    (head),hl        ; Init head pointer
  143.     ld    (tail),hl        ;   and tail pointer
  144.     xor    a
  145.     ret
  146.  
  147. ;..........
  148. ;
  149. ; BIOS intercept routines.  Only called if patched
  150. ;
  151. wboot:
  152.     ld    sp,stack        ; Insure valid stack
  153.     call    unpatch            ; Unpatch vectors
  154.     jp    xwboot            ; And on to BIOS
  155.  
  156. const:
  157.     ld    a,(xpend)        ; ^X pending?
  158.     or    a
  159.     jr    nz,consta
  160.     ld    a,(conchar)        ; Pending command?
  161.     jp    z,xconst        ; On to BIOS if not
  162. consta:
  163.     or    0ffh            ; Set to char ready
  164.     ret
  165.  
  166. conin:
  167.     ld    hl,xpend
  168.     ld    a,(hl)
  169.     ld    (hl),0            ; Reset ^X pending
  170.     or    a
  171.     jr    z,conin1
  172.     ld    a,ctrlx
  173.     ret                ; Clear line
  174. conin1:
  175.     ld    a,(conchar)        ; Char pending?
  176.     or    a
  177.     jr    nz,ischar
  178.     call    xconin            ; Get a char
  179.     cp    ctrlw            ; ^W ?
  180.     jr    z,set_hist
  181.     cp    ctrlv            ; ^V ?
  182.     jr    z,set_hist
  183.     cp    ctrll            ; ^L ?
  184.     ret    nz
  185.  
  186. set_hist:
  187.     ld    (conchar),a        ; Save char
  188.     ld    (xpend),a        ; Set ^X pending flag
  189.     ld    a,ctrlk            ; Return ^K to clear to end of line
  190.     ret
  191.  
  192. ischar:
  193.     cp    ctrll            ; Is it list history?
  194.     jr    z,listit
  195.     xor    a
  196.     ld    (count),a        ; Init count
  197. ischara:
  198.     ld    a,(count)        ; Get count of tries
  199.     cp    100            ; Arbitrary maximum
  200.     jr    nc,conina        ; Ignore if none
  201.     inc    a            ; Bump count
  202.     ld    (count),a
  203.     ld    hl,(cur_line)        ; Get current line addr
  204.     inc    hl            ; Test for 0FFFFh
  205.     ld    a,h
  206.     or    l
  207.     jr    z,ischar1        ; Jump if first
  208.     dec    hl
  209.     jr    ischar3
  210. ischar1:
  211.     ld    a,(conchar)        ; Get char
  212.     cp    ctrlw
  213.     ld    hl,(tail)        ; Get first ^W recall
  214.     jr    z,ischar2
  215.     ld    hl,(head)        ; Get first ^V recall
  216. ischar2:
  217.     ld    a,h
  218.     or    l            ; Test for none
  219.     jr    nz,aheadok        ; Onward if something in storage
  220. conina:
  221.     ld    a,(conchar)        ; Get pending char
  222.     call    unpatch            ; We will no longer intercept
  223.     ret
  224. ischar3:
  225.     ld    a,(conchar)        ; Get command
  226.     cp    ctrlw            ; ^W ?
  227.     jr    z,backup
  228.     inc    hl
  229.     inc    hl            ; point to next line addr
  230.     ld    e,(hl)
  231.     inc    hl
  232.     ld    d,(hl)            ; Get next line addr
  233.     ex    de,hl
  234.     ld    a,h
  235.     or    l            ; End of chain?
  236.     jr    nz,aheadok
  237.     ld    hl,(head)        ; Circle to head
  238. aheadok:
  239.     ld    (cur_line),hl        ; Save current line addr
  240.     ld    a,4
  241.     call    addhla            ; Offset to CCP flag
  242.     ld    a,(ccpflag)        ; Get CCP flag
  243.     cp    (hl)            ; Same?
  244.     jr    nz,ischara        ; Try again if not.
  245.     inc    hl
  246.     inc    hl            ; Offset to 2nd text char
  247.     ex    de,hl
  248.     ld    hl,(scbbase)        ; Get SCB addr
  249.     ld    l,0bah            ; Point to conin redirection addr
  250.     ld    (hl),e
  251.     inc    hl
  252.     ld    (hl),d            ; BDOS will now redirect console
  253.                     ;  input from our command line
  254.     xor    a
  255.     ld    (conchar),a        ; Reset for later
  256.     dec    de            ; Back to first char
  257.     ld    a,(de)
  258.     ret                ; Return with first char
  259. backup:
  260.     ld    hl,(cur_line)
  261.     ld    e,(hl)
  262.     inc    hl
  263.     ld    d,(hl)            ; Get PREV line addr
  264.     ex    de,hl
  265.     ld    a,h
  266.     or    l            ; At start of chain?
  267.     jr    nz,aheadok
  268.     ld    hl,(tail)
  269.     jr    aheadok
  270.  
  271. listit:
  272.     xor    a
  273.     ld    (count),a        ; Init page size count
  274.     ld    hl,(head)
  275.     ld    (list_line),hl        ; Init current list line
  276. list1:
  277.     ld    hl,(list_line)        ; Get current list line
  278.     ld    a,h
  279.     or    l            ; Done?
  280.     jr    z,list2
  281.     ld    a,4
  282.     call    addhla            ; Offset to CCP flag
  283.     ld    a,(ccpflag)        ; get ccp flag
  284.     cp    (hl)            ; Same?
  285.     inc    hl            ; Offset to text start
  286.     call    z,showline        ; Print it on console
  287.     ld    hl,(list_line)
  288.     inc    hl
  289.     inc    hl            ; Offset to NEXT addr
  290.     ld    e,(hl)
  291.     inc    hl
  292.     ld    d,(hl)
  293.     ld    (list_line),de        ; Save next list line
  294.     jr    list1            ; And loop for more
  295. list2:
  296.     call    spaces            ; Space over to current column
  297.     xor    a
  298.     ld    (conchar),a        ; Reset console char
  299.     jp    conin
  300.  
  301. ;........
  302. ;
  303. ; Turn up a new line and space over to current console column position
  304. ;
  305. spaces:
  306.     push    hl
  307.     call    crlf            ; Turn up a new line
  308.     ld    hl,(scbbase)
  309.     ld    l,0b7h            ; Point to current console column
  310.     ld    a,(hl)
  311.     or    a            ; Zero ?
  312.     jr    z,space2
  313.     ld    b,a
  314.     ld    c,' '            ; Space
  315. space1:
  316.     call    conout            ; output a space
  317.     djnz    space1
  318. space2:
  319.     pop    hl
  320.     ret
  321.  
  322. ;........
  323. ;
  324. ; Patch BIOS vectors
  325. ;
  326. patch:
  327.     push    bc
  328.     push    de
  329.     ld    hl,(1)
  330.     ld    de,xwboot
  331.     ld    bc,9
  332.     ldir                ; Save original BIOS vectors
  333.     ld    de,(1)
  334.     ld    hl,vwboot
  335.     ld    bc,9
  336.     ldir                ; Patch in intercept vectors
  337.     pop    de
  338.     pop    bc
  339.     ret
  340.  
  341. ;.........
  342. ;
  343. ; Restore original BIOS vectors
  344. ;
  345. unpatch:
  346.     push    de
  347.     ld    de,(1)
  348.     ld    hl,xwboot
  349.     ld    bc,9
  350.     ldir                ; Restore original vectors
  351.     pop    de
  352.     ret
  353.  
  354. xwboot:    ds    3
  355. xconst:    ds    3
  356. xconin:    ds    3
  357.  
  358. vwboot:    jp    wboot
  359. vconst:    jp    const
  360. vconin:    jp    conin
  361.  
  362. conout:
  363.     push    hl
  364.     push    bc
  365.     call    0
  366. xconout    equ    $-2
  367.     pop    bc
  368.     pop    hl
  369.     ret
  370.  
  371. ;.........
  372. ;
  373. ; Add a new line to line buffer area
  374. ;
  375. add_line:
  376.     ld    hl,(next_free)        ; Get addr of free area
  377.     add    hl,bc            ; Add in line length
  378.     ld    a,6
  379.     call    addhla            ; Account for header
  380.     push    de            ; Save source addr
  381.     ld    de,buff_end        ; Get addr of end
  382.     or    a
  383.     sbc    hl,de            ; Room left?
  384.     jr    c,buff_ok
  385.     call    fix_buff        ; Delete first entry and shuffle
  386.                     ;   things up.
  387.     pop    de            ; Restore source addr
  388.     jr    add_line        ; And try again
  389. buff_ok:
  390.     ld    hl,(tail)        ; Get current tail addr
  391.     ld    a,h
  392.     or    l            ; Anything there?
  393.     jr    nz,tailok
  394.     ld    hl,buff_start        ; Start at beginning
  395. tailok:
  396.     ld    de,(next_free)        ; Get free addr
  397.     inc    hl
  398.     inc    hl            ; Offset to NEXT addr
  399.     ld    (hl),e
  400.     inc    hl
  401.     ld    (hl),d            ; Save forward pointer
  402.     ex    de,hl
  403.     dec    de
  404.     dec    de
  405.     dec    de            ; Back to PREV pointer
  406.     ld    (tail),hl        ; Save new tail addr
  407.     ld    (hl),e
  408.     inc    hl
  409.     ld    (hl),d            ; Save back pointer
  410.     inc    hl
  411.     xor    a
  412.     ld    (hl),a
  413.     inc    hl
  414.     ld    (hl),a            ; Init new forward pointer
  415.     inc    hl
  416.     ld    a,(ccpflag)        ; Get CCP flag
  417.     ld    (hl),a            ; Init CCP flag
  418.     inc    hl            ; Point to start of text
  419.     pop    de            ; Get source addr
  420.     ex    de,hl            ; For LDIR
  421.     ldir                ; Move it into place
  422.     xor    a
  423.     ld    (de),a            ; Put in terminating zero
  424.     inc    de
  425.     ld    (next_free),de        ; Update next free addr
  426.     ld    hl,(head)        ; Get head addr
  427.     ld    a,h
  428.     or    l            ; Null?
  429.     ret    nz            ; Return if ok
  430.     ld    hl,(tail)
  431.     ld    (head),hl        ; If first, make head = tail
  432.     ld    (hl),a
  433.     inc    hl
  434.     ld    (hl),a            ; Zero first back pointer
  435.     ret
  436.  
  437. ;..........
  438. ;
  439. ; Delete first history line, and move things up
  440. ;
  441. fix_buff:
  442.     ld    hl,(head)        ; Get head addr
  443.     ld    a,h
  444.     or    l
  445.     ret    z            ; Return if nothing there
  446.     inc    hl
  447.     inc    hl            ; Offset to NEXT addr
  448.     ld    e,(hl)
  449.     inc    hl
  450.     ld    d,(hl)            ; Get addr of 2nd line
  451.     ld    a,d
  452.     or    e            ; Is there 2nd line?
  453.     jr    nz,moveok
  454.     ex    de,hl
  455.     ld    (head),hl        ; Zero head
  456.     ld    (tail),hl        ;   and tail
  457.     ld    hl,buff_start
  458.     ld    (next_free),hl        ; Init next free addr
  459.     ret
  460. moveok:
  461.     push    bc            ; Save length
  462.     ld    hl,(head)        ; Get head addr
  463.     push    de
  464.     ex    de,hl
  465.     or    a
  466.     sbc    hl,de            ; Calc amount of move
  467.     ld    (movlen),hl        ; Save it
  468.     ld    b,h
  469.     ld    c,l
  470.     ld    hl,buff_len        ; Get storage length
  471.     or    a
  472.     sbc    hl,bc            ; Calc length for LDIR
  473.     ld    b,h
  474.     ld    c,l
  475.     ld    hl,(head)        ; Get target of move
  476.     pop    de
  477.     ex    de,hl            ; Swap for LDIR
  478.     ldir                ; Move buffer down
  479.     ld    hl,(head)
  480.     xor    a
  481.     ld    (hl),a
  482.     inc    hl
  483.     ld    (hl),a            ; Init PREV pointer
  484.     inc    hl
  485. fix_loop:
  486.     ld    e,(hl)
  487.     inc    hl
  488.     ld    d,(hl)            ; Get NEXT pointer
  489.     ld    a,d
  490.     or    e            ; At end?
  491.     jr    z,fix_done
  492.     push    hl
  493.     ld    hl,(movlen)        ; Get move length
  494.     ex    de,hl
  495.     or    a
  496.     sbc    hl,de            ; Calc new NEXT pointer
  497.     ex    de,hl
  498.     pop    hl
  499.     ld    (hl),d
  500.     dec    hl
  501.     ld    (hl),e            ; Replace NEXT pointer
  502.     ex    de,hl
  503.     dec    de
  504.     dec    de
  505.     ld    (hl),e
  506.     inc    hl
  507.     ld    (hl),d            ; Update PREV pointer
  508.     inc    hl
  509.     jr    fix_loop
  510. fix_done:
  511.     dec    hl
  512.     dec    hl
  513.     dec    hl
  514.     ld    (tail),hl        ; Update new tail pointer
  515.     ld    hl,(next_free)
  516.     ld    de,(movlen)
  517.     or    a
  518.     sbc    hl,de            ; Calc new next free addr
  519.     ld    (next_free),hl
  520.     pop    bc            ; Restore BC
  521.     ret
  522.  
  523. ;.............
  524. ;
  525. ; Display a command line on console
  526. ;
  527. showline:
  528.     push    hl
  529.     ld    hl,count
  530.     ld    a,(hl)            ; Get count
  531.     inc    (hl)            ; Bump count
  532.     cp    page_size        ; screen full?
  533.     call    z,new_page
  534.     call    spaces            ; Turn up a new line and space over
  535.     pop    hl
  536. show1:
  537.     ld    a,(hl)
  538.     or    a            ; At end?
  539.     ret    z
  540.     inc    hl
  541.     ld    c,a
  542.     call    conout            ; Show the char
  543.     jr    show1
  544.  
  545. ;.......
  546. ;
  547. ; Prompt with [more] message
  548. ;
  549. new_page:
  550.     ld    (hl),0            ; Init line count
  551.     call    crlf            ; Turn up a new line
  552.     ld     hl,more
  553.     call    show1            ; Print [more]
  554.     call    xconin            ; Get any char
  555.     ld    hl,backsp
  556.     jr    show1            ; Backspace over [more] and exit
  557.  
  558. crlf:
  559.     ld    c,13
  560.     call    conout
  561.     ld    c,10
  562.     jp    conout
  563.  
  564.  
  565. addhla:
  566.     add    a,l
  567.     ld    l,a
  568.     ret    nc
  569.     inc    h
  570.     ret
  571.  
  572. ;............
  573. ;
  574. ; Data area
  575. ;
  576. delmsg:        db    13,10,'History RSX removed$'
  577. histmsg:    db    13,10,'History RSX active$'
  578. more:        db    '[more]',0
  579. backsp:        db    13,'      ',13,0
  580.  
  581. xpend:        ds    1        ; ^X pending flag
  582. head:        dw    0        ; Address of head
  583. tail:        dw    0        ; Address of tail
  584. scbbase:    ds    2        ; Address of SCB
  585. scbpb:        db    3ah
  586.         db    0
  587. initf:        db    0        ; Init flag
  588. conchar:    db    0        ; Current console char
  589. cur_line:    ds    2        ; Address of current line
  590. list_line:    ds    2        ; Address of list line
  591. movlen:        ds    2        ; Move length
  592. ccpflag:    ds    1        ; CCP active flag
  593. count:        ds    1        ; Count of max tries
  594. next_free:    dw    buff_start    ; Address of free ram
  595. buff_start:    ds    buff_len    ; Room for history lines
  596. buff_end    equ    $        ; Address of end
  597.         ds    6        ; Temp stack during WBoot
  598. stack        equ    $
  599.  
  600.     end
  601.